﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using Coevery.AppFramework.Extensions;
using Coevery.AppFramework.Metadata;
using Coevery.AppFramework.Utils;
using Coevery.AppFramework.WinForms.Controller;
using Coevery.AppFramework.WinForms.Controls;
using Coevery.AppFramework.WinForms.MVC;
using DevExpress.Data.Filtering;
using DevExpress.XtraBars;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Repository;
using ICSharpCode.Core;
using Coevery.AppFramework.WinForms.Extensions;
using Coevery.AppFramework.WinForms.Workspaces;
using Coevery.AppFramework.WinForms.Views;
using Coevery.AppFramework;
using Coevery.AppFramework.WinForms;
using System.Drawing;
using System.ComponentModel;
using Coevery.Domain.Impl;
using DomainFoto = Coevery.Domain.Impl.Foto;
using DomainInmueble = Coevery.Domain.Impl.Inmueble;
using System.IO;
using System.Web;

namespace Coevery.Win.InmuebleModule.Report
{
    public class InmuebleReportController : ObjectController
    {
        private IInmuebleReportView _inmuebleReportView;
        private IList _users;
        private RibbonControl _ribbon;

        private Guid _objectId;
        private string _objectName;

        public override IActionResult Execute(ActionParameters parameters)
        {
            _ribbon = parameters.Get<RibbonControl>("ribbonControl");
            _inmuebleReportView = ViewFactory.CreateView("DefaultInmuebleReportView") as IInmuebleReportView;

            _objectId = parameters.ObjectId;
            _objectName = parameters.ObjectName;
            
            OnViewSet();
            var result = new PartialViewResult();
            result.View = _inmuebleReportView;
            return result;
        }

        protected void OnViewSet()
        {
            _inmuebleReportView.SearchReport += new EventHandler(View_SearchReport);
            _inmuebleReportView.NameCellClicked += View_NameCellClicked;
            _inmuebleReportView.OnViewReady += _inmuebleReportView_OnViewReady;
            _users = _objectSpace.GetObjects("User");

            SetMenu();
        }

        void _inmuebleReportView_OnViewReady(object sender, EventArgs e)
        {
            OnViewReady();
        }

        public void OnViewReady()
        {
            //base.OnViewReady();
            var worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += (s, ex) =>
                {
                    ex.Result = GetInmuebleOverviewCollection();
                };
            worker.RunWorkerCompleted += WorkerRunWorkerCompleted;
            worker.RunWorkerAsync();
        }

        private void WorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!(e.Result is IEnumerable)) return;
            _inmuebleReportView.Bind((IEnumerable)e.Result);
        }

        void View_SearchReport(object sender, EventArgs e)
        {

        }

        void View_NameCellClicked(object sender, EventArgs<InmuebleIdealistaOverview> e)
        {
            //ShowEntityDetails<Inmueble.InmuebleDetailView>(EntityDetailWorkingMode.View, "Inmueble",
            //                                                      e.Data.InmuebleId);
        }

       
        private InmuebleOverviewCollection GetInmuebleOverviewCollection()
        {
            var inmueblesOverviewCollection = new InmuebleOverviewCollection();
            var inmuebleOverview = new InmuebleOverview();
            var overviewCollection = new InmuebleIdealistaOverviewCollection();
            var inmuebleIdealistaOverview = new InmuebleIdealistaOverview();

            inmueblesOverviewCollection.Add(inmuebleOverview);
            
            /*
            var extraColumns = new Dictionary<string, string>
                                   {
                                       {"OwnerName", "Owner == null?null:Owner.FullName"},
                                       {"TechnicianName", "Technician == null?null:Technician.FullName"},
                                       {"Contracts", "Contracts"},
                                       {"OriginatingLeadName", "OriginatingLead == null?null:OriginatingLead.Subject"},
                                       {"CustomerName", "Customer == null?null:Customer.Name"}
                                   };
            var predicate = GetPredicate();
            var notes = GetNotes();
            */
            var inmReport = _objectSpace.GetOrNew(_objectName, _objectId, "InmuebleIdealistas/Fotos");
            
            if (inmReport == null) return inmueblesOverviewCollection;

            IList<InmuebleIdealista> Precios = GetPropertyValue(inmReport, "InmuebleIdealistas") as IList<InmuebleIdealista>; //ContractTotal
            double precioMedio = 0.0, precio = 0.0;
            if (Precios.Count != 0)
            {
                 precioMedio = Math.Round(Precios.Select(o => Convert.ToDouble(o.Price) / Convert.ToDouble(o.Size)).Average());
            }

            precio = Math.Round(precioMedio * Convert.ToDouble((string)GetPropertyValue(inmReport, "Metros")));

            inmuebleOverview.PrecioMedio = precioMedio;
            inmuebleOverview.Precio = precio;

            var ccaaCode = (int?)GetPropertyValue(inmReport, "ComunidadAutonomaId"); 
            if (ccaaCode != null)
            {
                inmuebleOverview.ComunidadAutonomaId = GetLocalizedPickListValue("Inmueble", "ComunidadAutonomaId", ccaaCode.Value);
            }

            var provinciaCode = (int?)GetPropertyValue(inmReport, "ProvinciaId");
            if (provinciaCode != null)
            {
                inmuebleOverview.ProvinciaId = GetLocalizedPickListValue("Inmueble", "ProvinciaId", provinciaCode.Value);
            }

            SetPropertyValue(inmReport, "CodigoPostal", inmuebleOverview, "CodigoPostal");

            var municipioCode = (int?)GetPropertyValue(inmReport, "MunicipioId");
            if (municipioCode != null)
            {
                inmuebleOverview.MunicipioId = GetLocalizedPickListValue("Inmueble", "MunicipioId", municipioCode.Value);
            }
            
            SetPropertyValue(inmReport, "Barrio", inmuebleOverview, "Barrio");

            var tipoViaCode = (int?)GetPropertyValue(inmReport, "TipoViaId");
            if (tipoViaCode != null)
            {
                inmuebleOverview.TipoViaId = GetLocalizedPickListValue("Inmueble", "TipoViaId", tipoViaCode.Value);
            }

            SetPropertyValue(inmReport, "NombreVia", inmuebleOverview, "NombreVia");
            SetPropertyValue(inmReport, "Numero", inmuebleOverview, "Numero");
            SetPropertyValue(inmReport, "Planta", inmuebleOverview, "Planta");
            SetPropertyValue(inmReport, "Puerta", inmuebleOverview, "Puerta");
            SetPropertyValue(inmReport, "Escalera", inmuebleOverview, "Escalera");
                      
            var tipoViviendaCode = (int?)GetPropertyValue(inmReport, "TipoVivienda");
            if (tipoViviendaCode != null)
            {
                inmuebleOverview.TipoVivienda = GetLocalizedPickListValue("Inmueble", "TipoVivienda", tipoViviendaCode.Value);
            }

            SetPropertyValue(inmReport, "Catastro", inmuebleOverview, "Catastro");
            SetPropertyValue(inmReport, "Metros", inmuebleOverview, "Metros");
            SetPropertyValue(inmReport, "Habitaciones", inmuebleOverview, "Habitaciones");
            SetPropertyValue(inmReport, "Banios", inmuebleOverview, "Banios");

            var estadoCode = (int?)GetPropertyValue(inmReport, "Estado");
            if (estadoCode != null)
            {
                inmuebleOverview.Estado = GetLocalizedPickListValue("Inmueble", "Estado", estadoCode.Value);
            }

            var anioConstruccionCode = (int?)GetPropertyValue(inmReport, "AnioConstruccion");
            if (anioConstruccionCode != null)
            {
                inmuebleOverview.AnioConstruccion = GetLocalizedPickListValue("Inmueble", "AnioConstruccion", anioConstruccionCode.Value);
            }

            var anioReformaCode = (int?)GetPropertyValue(inmReport, "AnioReforma");
            if (anioReformaCode != null)
            {
                inmuebleOverview.AnioReforma = GetLocalizedPickListValue("Inmueble", "AnioReforma", anioReformaCode.Value);
            }

          
            SetPropertyValue(inmReport, "Amueblado", inmuebleOverview, "Amueblado");
            SetPropertyValue(inmReport, "CocinaEquipada", inmuebleOverview, "CocinaEquipada");
            SetPropertyValue(inmReport, "Garaje", inmuebleOverview, "Garaje");
            SetPropertyValue(inmReport, "Trastero", inmuebleOverview, "Trastero");
            SetPropertyValue(inmReport, "Jardin", inmuebleOverview, "Jardin");
            SetPropertyValue(inmReport, "Aire", inmuebleOverview, "Aire");
            SetPropertyValue(inmReport, "Calefaccion", inmuebleOverview, "Calefaccion");
            SetPropertyValue(inmReport, "Ascensor", inmuebleOverview, "Ascensor");
            SetPropertyValue(inmReport, "Latitud", inmuebleOverview, "Latitud");
            SetPropertyValue(inmReport, "Longitud", inmuebleOverview, "Longitud");

            foreach (var inmuebleIdealista in ((Inmueble)inmReport).InmuebleIdealistas)
            {
                inmuebleIdealistaOverview = new InmuebleIdealistaOverview();
                inmuebleOverview.InmuebleIdealistas.Add(inmuebleIdealistaOverview);
                SetPropertyValue(inmuebleIdealista, "InmuebleIdealistaId", inmuebleIdealistaOverview, "InmuebleIdealistaId");
                SetPropertyValue(inmuebleIdealista, "AbrAddress", inmuebleIdealistaOverview, "AbrAddress");
                SetPropertyValue(inmuebleIdealista, "Address", inmuebleIdealistaOverview, "Address");
                SetPropertyValue(inmuebleIdealista, "Agency", inmuebleIdealistaOverview, "Agency");
                SetPropertyValue(inmuebleIdealista, "AgentLogo", inmuebleIdealistaOverview, "AgentLogo");
                SetPropertyValue(inmuebleIdealista, "Bathrooms", inmuebleIdealistaOverview, "Bathrooms");
                SetPropertyValue(inmuebleIdealista, "Condition", inmuebleIdealistaOverview, "Condition");
                SetPropertyValue(inmuebleIdealista, "Country", inmuebleIdealistaOverview, "Country");
                SetPropertyValue(inmuebleIdealista, "Description", inmuebleIdealistaOverview, "Description");
                SetPropertyValue(inmuebleIdealista, "Distance", inmuebleIdealistaOverview, "Distance");

                if (((string)GetPropertyValue(inmuebleIdealista, "District")) != "")
                {
                    if (((string)GetPropertyValue(inmuebleIdealista, "Neighborhood")) != "")
                    {
                        inmuebleIdealistaOverview.District = (string)GetPropertyValue(inmuebleIdealista, "District") + "(" + GetPropertyValue(inmuebleIdealista, "Neighborhood") + ")";
                    }
                    else
                    {
                        inmuebleIdealistaOverview.District = (string)GetPropertyValue(inmuebleIdealista, "District");
                    }
                }
                else
                {
                    inmuebleIdealistaOverview.District = (string)GetPropertyValue(inmuebleIdealista, "Neighborhood");
                }

                SetPropertyValue(inmuebleIdealista, "FavComment", inmuebleIdealistaOverview, "FavComment");
                SetPropertyValue(inmuebleIdealista, "Favourite", inmuebleIdealistaOverview, "Favourite");
                SetPropertyValue(inmuebleIdealista, "Floor", inmuebleIdealistaOverview, "Floor");
                SetPropertyValue(inmuebleIdealista, "HasVideo", inmuebleIdealistaOverview, "HasVideo");
                SetPropertyValue(inmuebleIdealista, "Latitude", inmuebleIdealistaOverview, "Latitude");
                SetPropertyValue(inmuebleIdealista, "Longitude", inmuebleIdealistaOverview, "Longitude");
                SetPropertyValue(inmuebleIdealista, "Munipality", inmuebleIdealistaOverview, "Munipality");
                SetPropertyValue(inmuebleIdealista, "NumPhotos", inmuebleIdealistaOverview, "NumPhotos");
                SetPropertyValue(inmuebleIdealista, "PhotosUrl", inmuebleIdealistaOverview, "PhotosUrl");
                SetPropertyValue(inmuebleIdealista, "Position", inmuebleIdealistaOverview, "Position");
                SetPropertyValue(inmuebleIdealista, "Price", inmuebleIdealistaOverview, "Price");
                SetPropertyValue(inmuebleIdealista, "PropertyCode", inmuebleIdealistaOverview, "PropertyCode");
                SetPropertyValue(inmuebleIdealista, "PropertyType", inmuebleIdealistaOverview, "PropertyType");
                SetPropertyValue(inmuebleIdealista, "PropertyTypeCode", inmuebleIdealistaOverview, "PropertyTypeCode");
                SetPropertyValue(inmuebleIdealista, "Province", inmuebleIdealistaOverview, "Province");
                SetPropertyValue(inmuebleIdealista, "Region", inmuebleIdealistaOverview, "Region");
                SetPropertyValue(inmuebleIdealista, "Rooms", inmuebleIdealistaOverview, "Rooms");
                SetPropertyValue(inmuebleIdealista, "ShowAddress", inmuebleIdealistaOverview, "ShowAddress");
                SetPropertyValue(inmuebleIdealista, "Size", inmuebleIdealistaOverview, "Size");
                SetPropertyValue(inmuebleIdealista, "Subregion", inmuebleIdealistaOverview, "Subregion");
                SetPropertyValue(inmuebleIdealista, "Thumbnail", inmuebleIdealistaOverview, "Thumbnail");
                SetPropertyValue(inmuebleIdealista, "TipUsuCd", inmuebleIdealistaOverview, "TipUsuCd");
                SetPropertyValue(inmuebleIdealista, "Url", inmuebleIdealistaOverview, "Url");
                SetPropertyValue(inmuebleIdealista, "UserCode", inmuebleIdealistaOverview, "UserCode");
                SetPropertyValue(inmuebleIdealista, "VideoType", inmuebleIdealistaOverview, "VideoType");
                SetPropertyValue(inmuebleIdealista, "InmuebleId", inmuebleIdealistaOverview, "InmuebleId");       

                /* //Ejemplo agregación 
                var contracts = GetPropertyValue(inmuebleIdealista, "Contracts") as IList; //ContractTotal
                if (contracts != null)
                {
                    var contractTotal = contracts.AsQueryable().Select("TotalPrice").Cast<decimal?>().Sum();
                    overview.ContractTotal = contractTotal;
                }
                */

                double precioMedioIdealista = Math.Round(Convert.ToDouble((string)GetPropertyValue(inmuebleIdealistaOverview, "Price")) / Convert.ToDouble((string)GetPropertyValue(inmuebleIdealistaOverview, "Size")));
                inmuebleIdealistaOverview.AveragePrice = precioMedioIdealista;

                foreach (var fot in inmuebleIdealista.Fotos)
                {
                    DomainFoto foto = fot;
                    FotoOverview fotoOverview = new FotoOverview();
                    fotoOverview.Description = foto.FotoDesc;
                    fotoOverview.Img = (byte[])(new ImageConverter().ConvertTo(BestUsabilityCrop(Image.FromStream(new MemoryStream(foto.Img)), 160, 1), typeof(byte[])));
                    inmuebleIdealistaOverview.Add(fotoOverview);
                }
                overviewCollection.Add(inmuebleIdealistaOverview);
                //break; // Puesto para pintar solo un piso piloto a efectos de DEBUG
            }
            return inmueblesOverviewCollection;
        }



        private void GetDataRange(int? value, out DateTime startDate, out DateTime endDate)
        {
            startDate = new DateTime(2000, 1, 1);
            endDate = new DateTime(2050, 12, 31);
            if (value == null) return;
            if (Coevery.AppFramework.Utils.DateRang.DateRange.Custom == (Coevery.AppFramework.Utils.DateRang.DateRange)value.Value)
            {

                if (beginDateBar.EditValue != null)
                    startDate = (DateTime)beginDateBar.EditValue;
                if (endDateBar.EditValue != null)
                    endDate = (DateTime)endDateBar.EditValue;
            }
            else
            {
                DateRang.GetDataRange(value, out startDate, out endDate);
            }
        }

        private IEnumerable GetNotes()
        {
            CriteriaOperator filter = null;
            if (DataRangeValue != null)
            {
                DateTime startDate, endDate;
                GetDataRange(DataRangeValue, out startDate, out endDate);
                filter = new BinaryOperator("CreatedOn", startDate, BinaryOperatorType.GreaterOrEqual)
                        & new BinaryOperator("CreatedOn", endDate, BinaryOperatorType.LessOrEqual);
            }

            var notes = _objectSpace.GetObjects("Note", filter, null);
            return notes;
        }

        private CriteriaOperator GetPredicate()
        {
            CriteriaOperator filter = null;
            if (TechnicianIds.Count > 0)
                filter &= new InOperator("TechnicianId", TechnicianIds);

            if (OwnerIds.Count > 0)
                filter &= new InOperator("OwnerId", OwnerIds);

            if (statusItem.EditValue != null && statusItem.EditValue.ToString() != "-1")
            {
                filter &= new BinaryOperator("StatusCode", statusItem.EditValue);
            }

            if (DataRangeValue != null)
            {
                DateTime startDate, endDate;
                GetDataRange(DataRangeValue, out startDate, out endDate);
                filter &= new BinaryOperator("CreatedOn", endDate, BinaryOperatorType.LessOrEqual);
                GroupOperator nestedGroup = new GroupOperator(new OperandProperty("ClosedTime").IsNotNull(),
                    new BinaryOperator("ClosedTime", startDate, BinaryOperatorType.GreaterOrEqual),
                    new BinaryOperator("ClosedTime", endDate, BinaryOperatorType.LessOrEqual));
                nestedGroup.OperatorType = GroupOperatorType.And;
                GroupOperator group = new GroupOperator(new UnaryOperator(UnaryOperatorType.IsNull, "ClosedTime"), nestedGroup);
                group.OperatorType = GroupOperatorType.Or;

                filter &= group;
            }
            return filter;
        }

        private string GetLocalizedPickListValue(string entityName, string attributeName, int value)
        {
            var entity = MetadataRepository.Entities.First(e => e.PhysicalName == entityName);
            var attribute = entity.Attributes.First(a => a.PhysicalName == attributeName);
            if (attribute.OptionSet == null)
                return null;

            var pickListValue = attribute.OptionSet.AttributePicklistValues.FirstOrDefault(v => v.Value == value);
            if (pickListValue == null)
                return value.ToString(CultureInfo.InvariantCulture);
            //throw new ApplicationException(string.Format("The property {0} of {1} doesn't have the value: {2}", attributeName, entityName, value));
            var culture = System.Globalization.CultureInfo.CurrentCulture;
            var localizedLabels = MetadataRepository.LocalizedLabels
                .Where(l => l.ObjectId == pickListValue.AttributePicklistValueId);

            var localizedLabel = localizedLabels.FirstOrDefault(l => l.LanguageId == culture.LCID) ??
                                 localizedLabels.First();
            return localizedLabel.Label;
        }

        private void SetPropertyValue(object source, string sourceProperty, object target, string targetProperty)
        {
            var sourcePropertyInfo = source.GetType().GetProperty(sourceProperty);
            var targetPropertyInfo = target.GetType().GetProperty(targetProperty);
            targetPropertyInfo.SetValue(target, sourcePropertyInfo.GetValue(source, null), null);
        }

        private object GetPropertyValue(object source, string sourceProperty)
        {
            var sourcePropertyInfo = source.GetType().GetProperty(sourceProperty);
            return sourcePropertyInfo.GetValue(source, null);
        }

        protected string GetLocalizedCaption(string name)
        {
            return StringParser.Parse("${res:" + name + "}");
        }
        private void SetMenu()
        {
            //RibbonPage generalPage = (RibbonPage)WorkItem.RootWorkItem.UIExtensionSites[ExtensionSiteNames.Ribbon].First();
            RibbonControl ribbon = this._ribbon;
            RibbonController control = new RibbonController(ribbon, _inmuebleReportView.ReportPrintControl);
            ribbon.AutoSizeItems = true;
            string groupName = "GeneralPageGroup";
            InitStatus(groupName, ribbon.Pages[0].Groups[0]);
            InitTechnicianPerson(groupName, ribbon.Pages[0].Groups[0]);
            InitSalePerson(groupName, ribbon.Pages[0].Groups[0]);
            InitDateRang(groupName, ribbon.Pages[0].Groups[0]);
            InitDate(groupName, ribbon.Pages[0].Groups[0]);
            InitSearchButton(groupName, ribbon.Pages[0].Groups[0]);
        }


        private void BindEnum<T>(RepositoryItemLookUpEdit lookUpEdit, string emptyText, int? emptyValue)
        {
            var statusTypeNames = Enum.GetNames(typeof(T));
            var statusItems = statusTypeNames
                .Select(name => new LookupListItem<int?>
                {
                    DisplayName = GetLocalizedCaption(name),
                    Value = (int)Enum.Parse(typeof(T), name)
                }).ToList();
            if (!string.IsNullOrEmpty(emptyText))
            {
                string localizedEmptyText = GetLocalizedCaption(emptyText);
                statusItems.Insert(0, new LookupListItem<int?> { DisplayName = localizedEmptyText, Value = emptyValue });
            }
            lookUpEdit.Properties.InitializeLookUpEdit(statusItems);
        }

        BarEditItem statusItem;
        private void InitStatus(string groupName, RibbonPageGroup ribbonGroup)
        {
            statusItem = new BarEditItem();
            statusItem.Width = 100;
            statusItem.Caption = GetLocalizedCaption("Status");
            statusItem.CaptionAlignment = DevExpress.Utils.HorzAlignment.Near;
            RepositoryItemLookUpEdit statusData = new RepositoryItemLookUpEdit();
            BindEnum<InmuebleStatus>(statusData, "All", -1);
            statusItem.Edit = statusData;
            ribbonGroup.ItemLinks.Add(statusItem);

        }

        private List<Guid> TechnicianIds
        {
            get { return technicianData.GetSelection(); }
        }
        RepositoryItemPopupContainerEdit technicianData;
        private void InitTechnicianPerson(string groupName, RibbonPageGroup ribbonGroup)
        {
            BarEditItem technicianItem = new BarEditItem();
            technicianItem.Width = 100;
            technicianItem.Caption = GetLocalizedCaption("TechnologyPerson");
            technicianItem.CaptionAlignment = DevExpress.Utils.HorzAlignment.Near;
            technicianData = new RepositoryItemPopupContainerEdit();
            technicianData.InitEdit("User", "Department", true);
            technicianItem.Edit = technicianData;
            ribbonGroup.ItemLinks.Add(technicianItem);

        }

        private List<Guid> OwnerIds
        {
            get { return saleData.GetSelection(); }
        }
        RepositoryItemPopupContainerEdit saleData;
        private void InitSalePerson(string groupName, RibbonPageGroup ribbonGroup)
        {
            BarEditItem saleItem = new BarEditItem();
            saleItem.Width = 100;
            saleItem.Caption = GetLocalizedCaption("OwnerPerson");
            saleItem.CaptionAlignment = DevExpress.Utils.HorzAlignment.Near;
            saleData = new RepositoryItemPopupContainerEdit();
            saleData.InitEdit("User", "Department", true);
            saleItem.Edit = saleData;
            ribbonGroup.ItemLinks.Add(saleItem, true);

        }

        public int? DataRangeValue
        {
            get
            {
                int dataRangeValue = -1;
                if (dateRangItem.EditValue != null)
                    int.TryParse(dateRangItem.EditValue.ToString(), out dataRangeValue);
                if (dataRangeValue != -1) return dataRangeValue;
                return null;
            }
        }

        BarEditItem dateRangItem;
        private void InitDateRang(string groupName, RibbonPageGroup ribbonGroup)
        {
            dateRangItem = new BarEditItem();
            dateRangItem.Width = 100;
            dateRangItem.Caption = GetLocalizedCaption("DateRang");
            dateRangItem.EditValue = 1;
            dateRangItem.CaptionAlignment = DevExpress.Utils.HorzAlignment.Near;
            RepositoryItemImageComboBox dateRangData = new RepositoryItemImageComboBox();
            dateRangItem.EditValueChanged += (sender, e) =>
            {
                var visibility = DataRangeValue == (int)Coevery.AppFramework.Utils.DateRang.DateRange.Custom
                             ? BarItemVisibility.Always
                             : BarItemVisibility.Never;
                beginDateBar.Visibility = visibility;
                endDateBar.Visibility = visibility;
            };
            var statusTypeNames = Enum.GetNames(typeof(Coevery.AppFramework.Utils.DateRang.DateRange));
            var statusItems = statusTypeNames
                .Select(name => new LookupListItem<int?>
                {
                    DisplayName = GetLocalizedCaption(name),
                    Value = (int)Enum.Parse(typeof(Coevery.AppFramework.Utils.DateRang.DateRange), name)
                }).ToList();

            string localizedEmptyText = GetLocalizedCaption("All");
            statusItems.Insert(0, new LookupListItem<int?> { DisplayName = localizedEmptyText, Value = -1 });
            foreach (var item in statusItems)
            {
                dateRangData.Items.Add(new ImageComboBoxItem(item.DisplayName, item.Value, -1));
            }
            dateRangItem.Edit = dateRangData;
            ribbonGroup.ItemLinks.Add(dateRangItem);

        }

        BarEditItem beginDateBar;
        BarEditItem endDateBar;
        private void InitDate(string groupName, RibbonPageGroup ribbonGroup)
        {
            beginDateBar = new BarEditItem();
            beginDateBar.Visibility = BarItemVisibility.Never;
            beginDateBar.Width = 100;
            beginDateBar.Caption = GetLocalizedCaption("BeginDate");
            beginDateBar.CaptionAlignment = DevExpress.Utils.HorzAlignment.Near;
            RepositoryItemDateEdit begindateValue = new RepositoryItemDateEdit();
            beginDateBar.Edit = begindateValue;
            ribbonGroup.ItemLinks.Add(beginDateBar, true);



            endDateBar = new BarEditItem();
            endDateBar.Visibility = BarItemVisibility.Never;
            endDateBar.Width = 100;
            endDateBar.Caption = GetLocalizedCaption("EndDate");
            endDateBar.CaptionAlignment = DevExpress.Utils.HorzAlignment.Near;
            RepositoryItemDateEdit enddateValue = new RepositoryItemDateEdit();
            endDateBar.Edit = enddateValue;
            ribbonGroup.ItemLinks.Add(endDateBar);

        }

        private void InitSearchButton(string groupName, RibbonPageGroup ribbonGroup)
        {
            var buttonItem = new BarButtonItem() { Caption = GetLocalizedCaption("Search") };

            var icon = WinFormsResourceService.GetIcon("search");
            Image largeImage = icon.ToBitmap();
            buttonItem.LargeGlyph = largeImage;
            buttonItem.Glyph = new Bitmap(largeImage, new Size(16, 16));


            buttonItem.ItemClick += (sender, e) =>
            {
                var worker = new BackgroundWorker();
                worker.WorkerSupportsCancellation = true;
                worker.DoWork += (s, ex) =>
                {
                    ex.Result = GetInmuebleOverviewCollection();
                };
                worker.RunWorkerCompleted += WorkerRunWorkerCompleted;
                worker.RunWorkerAsync();
            };
            ribbonGroup.ItemLinks.Add(buttonItem, true);

        }

        public static Image Crop(Image src, int top, int left, int bottom, int right)
        {

            // Make the destination rectangle 30 percent wider and 30 percent taller than the original image. 
            // Put the upper-left corner of the destination rectangle at (150, 20). 
            RectangleF destinationRect = new RectangleF(0, 0, 160, 160);
            Bitmap target = new Bitmap(160, 160);

            // Draw a portion of the image. Scale that portion of the image 
            // so that it fills the destination rectangle.
            RectangleF sourceRect = new RectangleF(left, top, 160, 160);

            using (Graphics g = Graphics.FromImage(target))
            {
                g.DrawImage(src, destinationRect, sourceRect, GraphicsUnit.Pixel);
            }

            return target;
        }

        public static Image resizeImage(Image originalImage, int newWidth, int newHeight, float factor)
        {// Indica nuevo Width y/o nuevo Height. Si no se indican los dos, mantiene el ratio
            if (factor != null && factor != 0)
                return originalImage.GetThumbnailImage((int)(originalImage.Width * factor), (int)(originalImage.Height * factor), null, IntPtr.Zero);
            if (newWidth != null && newWidth != 0)
                return originalImage.GetThumbnailImage(newWidth, (newWidth * originalImage.Height) / originalImage.Width, null, IntPtr.Zero);
            if (newHeight != null && newHeight != 0)
                return originalImage.GetThumbnailImage((originalImage.Width * newHeight) / originalImage.Height, newHeight, null, IntPtr.Zero);
            if (newWidth != null && newWidth != 0 && newHeight != null && newHeight != 0)
                return originalImage.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
            return originalImage;
        }

        public static Image BestUsabilityCrop(Image image, int side, decimal targetRatio)
        {
            image = resizeImage(image, 0, 0, (float)((float)side / (float)(Math.Min(image.Width, image.Height))));
            //image.Save("C:\\Users\\Guest\\TEMP"+new Random().Next()+".jpg");

            decimal currentImageRatio = image.Width / (decimal)image.Height;
            int difference;

            //image is wider than targeted
            if (currentImageRatio > targetRatio)
            {
                int targetWidth = Convert.ToInt32(Math.Floor(targetRatio * image.Height));
                difference = image.Width - targetWidth;
                int left = Convert.ToInt32(Math.Floor(difference / (decimal)2));
                int right = Convert.ToInt32(Math.Ceiling(difference / (decimal)2));
                return Crop(image, 0, left, 0, right);
            }
            //image is higher than targeted
            else if (currentImageRatio < targetRatio)
            {
                int targetHeight = Convert.ToInt32(Math.Floor(image.Width / targetRatio));
                difference = image.Height - targetHeight;
                int top = Convert.ToInt32(Math.Floor(difference / (decimal)2));
                int bottom = Convert.ToInt32(Math.Ceiling(difference / (decimal)2));
                return Crop(image, top, 0, bottom, 0);
            }
            return image;
        }

        #region no user

        public override object SelectedObject
        {
            get { throw new NotImplementedException(); }
        }
        #endregion
    }

}
